package blue.web.dao.service;


import blue.commons.enums.StatusEnum;
import blue.tools.constants.BlueContants;
import blue.dao.base.BaseMapper;
import blue.dao.base.BaseModel;
import blue.erp.model.BlueSchool;
import blue.web.cache.service.RedisService;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;


public abstract class BaseService<T extends BaseModel> {

    @Autowired
    RedisService redisService;

    private org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
    public abstract BaseMapper getBaseMapper();


    public T selectByPrimaryKey(Object id,Long schoolId) {

        if(schoolId==null || schoolId.longValue()<=0){
            return null;
        }

        T selected=(T) getBaseMapper().selectByPrimaryKey(id);

        if(selected==null){
            return selected;
        }

        if(selected instanceof BlueSchool
                || selected.getSchoolid()==null || selected.getSchoolid()<1){//有些通用配置，不需要设置学校的
            return selected;
        }

        if(selected.getSchoolid()==null || schoolId.longValue()!=selected.getSchoolid().longValue()){
            return null;
        }
        return selected;
    }

    public int deleteByPrimaryKey(Object id,Long schoolId) {
        logger.info(String.format("deleteByPrimaryKey id=%s,schoolId=%s",id,schoolId));
        T selected=selectByPrimaryKey(id,schoolId);
        this.clearCache(schoolId);
        if(selected!=null){
            return getBaseMapper().deleteByPrimaryKey(id);
        }

        return 0;
    }


    public int baseSave(T record, Object example) {

        if (record == null) {
            return 0;
        }
        record.setUpdateTime(new Date());
//        this.clearCache(record.getSchoolid());
        logger.info(String.format("baseSave record=%s",JSONObject.toJSONString(record)));
        if (record.getId() != null) {
            return getBaseMapper().updateByPrimaryKeySelective(record);
        } else {

            List<T> baseList = this.select(example);

            if (CollectionUtils.isEmpty(baseList)) {
                record.setCreateTime(new Date());
                record.setStatus((byte) StatusEnum.Init.getValue());
                return getBaseMapper().insert(record);
            } else {
                if (baseList.size() == 1) {
                    record.setId(baseList.get(0).getId());
                    return getBaseMapper().updateByPrimaryKeySelective(record);
                }
            }
        }


        return 0;
    }


    public List<T> select(Object example) {

        try {
            Class classObject=example.getClass();
            Method[] methods=classObject.getDeclaredMethods();
            if(methods.length>0){
                for(Method method:methods){
                    if(method.getName().equalsIgnoreCase("setOrderByClause")){
                        method.invoke(example,"update_time desc");
                    }
                }
            }
        }catch (Exception e){

        }

        return getBaseMapper().selectByExample(example);
    }


    public Object baseSelectByPrimaryKey(Long id, String prefix,Long schoolId, boolean flush, Long timeout) {

        Object cache = redisService.getValue(String.format("%s_%s_%s",prefix,schoolId,id.toString()));

        if (!flush && cache != null) {

            return cache;
        } else {
            T data = selectByPrimaryKey(id,schoolId);

            if (data != null) {
                redisService.setValue(String.format("%s_%s_%s",prefix,schoolId,id.toString()), JSONObject.toJSONString(data), timeout);
            }

            return JSONObject.toJSONString(data);

        }

    }


    public Object baseSelectByPrimaryKey(Long id, String prefix, Long schoolId,boolean flush) {

        return baseSelectByPrimaryKey(id, prefix, schoolId,flush, BlueContants.day);
    }

    public abstract void clearCache(Long schoolId,Object... extend);

}
